package web.base;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class ServletUtil {

	public static void download(HttpServletResponse response, File file, boolean gzip) {
		if (file.exists()) {
			try {
				download(response, file.getName(), Files.readAllBytes(file.toPath()), gzip);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void download(HttpServletResponse response, String name, byte[] rawData, boolean gzip) {
		if(rawData == null){
			return ;
		}
		
		try {
			response.reset();
			response.setContentType("application/x-msdownload");
			
			byte[] data = rawData;
			String filename = "";
			if(gzip){
				data = compress(rawData);
				filename = URLEncoder.encode(name + ".gz", "UTF-8");
			}else{
				filename = URLEncoder.encode(name, "UTF-8");
			}
			response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
			response.setContentLength(data.length);
			
			if (data.length != 0) {
				OutputStream os = null;
				try {
					os = response.getOutputStream();
					os.write(data);

					os.flush();
				} finally {
					if (os != null)
						os.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static byte[] compress(byte[] data) throws IOException{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPOutputStream gos = null;
		try {
			gos = new GZIPOutputStream(bos);
			
			gos.write(data);
			gos.finish();
			gos.flush();
		} finally{
			if(gos != null) gos.close();
		}
		
		return bos.toByteArray();
	}
	
	public static byte[] uncompress(byte[] data) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPInputStream gis = null;
		try {
			gis = new GZIPInputStream(new ByteArrayInputStream(data));

			byte[] buffer = new byte[8192];
			int n = 0;
			while ((n = gis.read(buffer)) >= 0) {
				bos.write(buffer, 0, n);
			}
		} finally {
			if (gis != null)
				gis.close();
		}

		return bos.toByteArray();
	}
	
	public static Map<String, Object> parseUpload(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		
		try{
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			
			if(isMultipart){
				// Create a factory for disk-based file items
				DiskFileItemFactory factory = new DiskFileItemFactory();

				// Configure a repository (to ensure a secure temp location is used)
				File repository = new File("/data/log/upload");
				if(!repository.exists()){
					repository.mkdirs();
				}
				factory.setRepository(repository);

				// Create a new file upload handler
				ServletFileUpload upload = new ServletFileUpload(factory);
				// Set overall request size constraint
				upload.setSizeMax(1024*1024);

				// Parse the request
				List<FileItem> items = upload.parseRequest(request);
				
				// Process the uploaded items
				Iterator<FileItem> iter = items.iterator();
				while (iter.hasNext()) {
				    FileItem item = iter.next();

				    if (item.isFormField()) {
				    	String name = item.getFieldName();
				        String value = item.getString();
				        map.put(name, value);
				    } else {
				    	map.put(item.getFieldName(), item.get());
				    }
				}
			}
		}catch(Exception e){
			throw new RuntimeException(e.getMessage(), e);
		}
		
		return map;
	}
	
	public static byte[] readGzipFile(File f){
		try {
			byte[] gzipData = Files.readAllBytes(f.toPath());
			return uncompress(gzipData);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static void main(String[] args) {
		File f = new File("/data/1.txt");
		System.err.println(f.length());
	}
	
}
